#include "db_operator.h"


CDbOperator::CDbOperator()
{
	m_mysql = mysql_init(NULL);
	m_MysqlInfo = CAllConfigure::GetInstance().GetMysqlServerConfiguration();
	StoreMachineData = new std::thread(&CDbOperator::threadStoreDatabase, this);
}

void CDbOperator::threadStoreDatabase()
{
	while(true)
	{

		if(!qAllNeedStoreData.empty())		// something need to be stored
		{
			stStoreMachineData tempStoreDB = qAllNeedStoreData.front();
			if (true == CDbOperator::GetInstance().InserDataToDB(tempStoreDB.clientKey,tempStoreDB.memoryLimit,
						tempStoreDB.cpuLimit, tempStoreDB.processesLimit))
			{
				databaseMutex.lock();
				qAllNeedStoreData.pop();
				databaseMutex.unlock();
			}
			else
			{
				if (!m_mysql)
				{
					m_mysql = mysql_init(NULL);
				}
				Connect();
			}
		}

	}
}

CDbOperator::~CDbOperator()
{
	DisConnect();
	StoreMachineData->join();
	delete StoreMachineData;
}


bool CDbOperator::Connect()
{
	std::string strErr;
	int ml_outtime = 10;
	mysql_options(m_mysql, MYSQL_OPT_CONNECT_TIMEOUT, &ml_outtime);

	if (0 != mysql_options(m_mysql, MYSQL_SET_CHARSET_NAME, "utf8"))//设置字符集utf8
	{
		m_bConnectDb = false;
		ERROR_MSG("set charset error , reason: " <<  mysql_error(m_mysql));
		return false;
	}

	if (mysql_real_connect(m_mysql, m_MysqlInfo.cMysqlAddr.c_str(), m_MysqlInfo.cUsername.c_str(), m_MysqlInfo.cPassword.c_str(),	m_MysqlInfo.cDatabase.c_str(), m_MysqlInfo.uiPort, NULL, 0) == NULL)
	{
		m_bConnectDb = false;
		ERROR_MSG("connect mysql error , reason: " << mysql_error(m_mysql));
		return false;
	}
	else
	{
		std::string strSql = "set interactive_timeout=24*3600";
		int nRet = mysql_real_query(m_mysql, strSql.c_str(), (unsigned long)strSql.size());
		if (nRet != 0)
		{
			m_bConnectDb = false;
			ERROR_MSG("execuse sql error , reason: " << mysql_error(m_mysql));
			return false;
		}
	}

	m_bConnectDb = true;
	return m_bConnectDb;
}

void CDbOperator::DisConnect()
{
	mysql_close(m_mysql);
}

bool CDbOperator::InserDataToDB(const std::string& clientKey, const unsigned int& memory,
						const unsigned int& cpu, const unsigned int& processes)
{
	std::ostringstream inserSql;
	inserSql << "INSERT INTO `ClientData`.`collections` (`clientkey`, `memory`, `cpu`,`processes`) VALUES (\""
	<< clientKey << "\"" << ',' << memory << ',' << cpu << ',' << processes << ")" ;
	

	std::string cInsertSql;
	cInsertSql.assign(inserSql.str());
	INFO_MSG("insert sql: " << cInsertSql.c_str());
	int nRet = mysql_real_query(m_mysql, cInsertSql.c_str(), (unsigned long)cInsertSql.size());
	if (nRet != 0)
	{
		ERROR_MSG("execuse insert sql error , reason: " <<  mysql_error(m_mysql));
		return false;
	}
	
	return true;
}

void CDbOperator::PushBackToDbQueue(const stStoreMachineData& needStoreData)
{
	databaseMutex.lock();
	qAllNeedStoreData.push(needStoreData);
	databaseMutex.unlock();
}

